
KMG.LocalBackgroundObject = function ( context, config ) {

	KMG.BaseObject.call( this );
	var scope = this;
	this.config = config;
	this.context = context;

	this.geometry = new THREE.SphereGeometry( 500, 20, 10 );
	this.geometry.computeTangents();
	this.material = new THREE.MeshBasicMaterial({
		color: 0x00ff00,
		side: THREE.DoubleSide,
		depthTest: false,
		depthWrite: false,
		//wireframe: true
	});
	this.mesh = new THREE.Mesh( this.geometry, this.material );
	this.add(this.mesh);

	this.update = function()
	{

	};

};
KMG.LocalBackgroundObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.LocalGridObject = function ( context, config ) {

	KMG.BaseObject.call( this );
	var scope = this;
	this.config = config;
	this.context = context;

	this.createGeometry = function()
	{
		this.geometry = new THREE.Geometry( );
		for (var i = 0; i <= 100; i++) {
			var p1 = new THREE.Vector3(-5000, i * 100 - 5000, 0);
			var p2 = new THREE.Vector3(5000, i * 100 - 5000, 0);
			this.geometry.vertices.push(p1);
			this.geometry.vertices.push(p2);
		}
		for (var i = 0; i <= 100; i++) {
			var p1 = new THREE.Vector3(i * 100 - 5000, -5000, 0);
			var p2 = new THREE.Vector3(i * 100 - 5000, 5000, 0);
			this.geometry.vertices.push(p1);
			this.geometry.vertices.push(p2);
		}
		this.geometry.computeFaceNormals();
		this.material = new THREE.LineBasicMaterial({
			color: 0x03297e,
			linewidth: 2,
			opacity: 0.5,
			transparent: true,
			side: THREE.FrontSide,
			depthTest: false,
			depthWrite: false,
		});
		this.line = new THREE.Line( this.geometry, this.material, THREE.LinePieces );
		this.add(this.line);
	}
	this.createGeometry();

	this.update = function()
	{

	};

};
KMG.LocalGridObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.LocalModelObject = function ( context, config ) {

	KMG.BaseObject.call( this );
	var scope = this;
	this.config = config;
	this.context = context;
    var loader = new THREE.STLLoader();
    loader.addEventListener( 'load', function ( event ) {

        var geometry = event.content;
        var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
        var mesh = new THREE.Mesh( geometry, material );
        //mesh.scale.set( 0.02, 0.02, 0.02 );
        mesh.castShadow = false;
        mesh.receiveShadow = false;
		scope.add(mesh);

    } );
    loader.load( './assets/earth/model.stl' );


//添加FBX模型
    function addFBXModel(modelurl) {
        var manager = new THREE.LoadingManager();
        manager.onProgress = function( item, loaded, total ) {

            console.log( item, loaded, total );

        };

        var onProgress = function( xhr ) {

            if ( xhr.lengthComputable ) {

                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log( Math.round( percentComplete, 2 ) + '% downloaded' );

            }

        };

        var onError = function( xhr ) {

            console.error( xhr );

        };

        var loader = new THREE.FBXLoader( manager );
        loader.load( modelurl, function( object ) {

            scope.add( object );
            //addDragControl(object);

        }, onProgress, onError );
    }
    //addFBXModel("./assets/model/BMW_75.fbx")
	this.update = function()
	{

	};

};
KMG.LocalModelObject.prototype = Object.create( KMG.BaseObject.prototype );


KMG.LocalEffectsComposer = function(context, renderer) {

	var renderTargetParameters = {
		minFilter: THREE.LinearFilter,
		magFilter: THREE.LinearFilter,
		format: THREE.RGBAFormat,
		stencilBuffer: false
	};

	THREE.EffectComposer.call( this, renderer );
	var scope = this;
	this.context = context;
	this.renderer = renderer;

	var baseRenderPass = new THREE.RenderPass( context.baseScene, context.baseCamera );
	baseRenderPass.clear = true;
	this.addPass( baseRenderPass );

	var mainRenderPass = new THREE.RenderPass( context.mainScene, context.mainCamera );
	mainRenderPass.clear = false;
	this.addPass( mainRenderPass );

	var effectMainRenderPass = new THREE.RenderPass( context.effectScene, context.mainCamera );
	effectMainRenderPass.clear = false;
	this.addPass( effectMainRenderPass );

	var effectMainFXAA = new THREE.ShaderPass( THREE.FXAAShader );
	this.addPass( effectMainFXAA );

	var effectMainHBlur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
	this.addPass( effectMainHBlur );
	var effectMainVBlur = new THREE.ShaderPass( THREE.VerticalBlurShader );
	this.addPass( effectMainVBlur );

	var effectMainBloom = new THREE.BloomPass( 0.0 );
	this.addPass( effectMainBloom );

	var effectSave = new THREE.SavePass( new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, renderTargetParameters ) );
	effectSave.clear = false;
	this.addPass( effectSave );

	var clearDepthPass = new THREE.ClearDepthPass( );
	clearDepthPass.clear = false;
	this.addPass( clearDepthPass );

	var effectRenderPass = new THREE.RenderPass( context.effectScene, context.mainCamera );
	effectRenderPass.clear = true;
	effectRenderPass.clearAlpha = 0;
	effectRenderPass.clearColor = 0x000000;
	this.addPass( effectRenderPass );

	var depthPass = new THREE.DepthPass( );
	depthPass.clear = false;
	this.addPass( depthPass );

	var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
	this.addPass( effectFXAA );

	var effectBloom = new THREE.BloomPass( 0.0 );
	this.addPass( effectBloom );

	var effectHBlur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
	this.addPass( effectHBlur );
	var effectVBlur = new THREE.ShaderPass( THREE.VerticalBlurShader );
	this.addPass( effectVBlur );

	var effectBlend = new THREE.ShaderPass( THREE.MixTextureShader, "tDiffuse1" );
	effectBlend.uniforms[ 'opacity' ].value = 1.0;
	effectBlend.uniforms[ 'tDiffuse2' ].value = effectSave.renderTarget;
	effectBlend.renderToScreen = true;
	this.addPass( effectBlend );

	//var effectCopy = new THREE.ShaderPass( THREE.CopyShader );
	//effectCopy.renderToScreen = true;
	//this.addPass( effectCopy );

	this.effect = 1;
	this.opacity = 0;
	this.sender = null;
	this.callback = null;
	this.enterEffect = function(callback, sender) {
		this.effect = 1;
		this.opacity = 0;
		this.sender = sender;
		this.callback = callback;
	};
	this.exitEffect = function(callback, sender) {
		this.effect = 0;
		this.opacity = 1;
		this.sender = sender;
		this.callback = callback;
	};

	this.update = function() {
		if (this.effect == 0) {
			this.opacity -= 0.05;
			if (this.opacity < 0) {
				this.opacity = 0;
				if (this.callback != null) {
					this.callback(this.sender);
					this.sender = null;
					this.callback = null;
				}
			}
		} else {
			this.opacity += 0.05;
			if (this.opacity > 1) {
				this.opacity = 1;
				if (this.callback != null) {
					this.callback(this.sender);
					this.sender = null;
					this.callback = null;
				}
			}
		}

		var mainBlurAmount = 0.0;
		effectMainHBlur.uniforms[ 'h' ].value = mainBlurAmount / ( window.innerWidth / 2 );
		effectMainVBlur.uniforms[ 'v' ].value = mainBlurAmount / ( window.innerHeight / 2 );
		effectMainFXAA.uniforms["resolution"].value.x = 1 / window.innerWidth;
		effectMainFXAA.uniforms["resolution"].value.y = 1 / window.innerHeight;
		effectMainBloom.copyUniforms["opacity"].value = 0.8;

		var effectBlurAmount = 0.0;
		effectHBlur.uniforms[ 'h' ].value = effectBlurAmount / ( window.innerWidth / 2 );
		effectVBlur.uniforms[ 'v' ].value = effectBlurAmount / ( window.innerHeight / 2 );
		effectFXAA.uniforms["resolution"].value.x = 1 / window.innerWidth;
		effectFXAA.uniforms["resolution"].value.y = 1 / window.innerHeight;
		effectBloom.copyUniforms["opacity"].value = 5.0;

		effectBlend.uniforms[ 'opacity' ].value = this.opacity;
		effectBlend.uniforms[ 'tDiffuse2' ].value = effectSave.renderTarget;
	};

};
KMG.LocalEffectsComposer.prototype = Object.create( THREE.EffectComposer.prototype );


KMG.LocalScene = function ( domElement, config ) {

	var scope = this;
	this.config = config;
	this.domElement = ( domElement !== undefined ) ? domElement : document;
	this.visible = true;

	this.context = {
		container : null,
		composer : null,
		renderer : null,
		baseCamera : null,
		baseScene : null,
		mainCamera : null,
		mainScene : null,
		effectScene : null,
		containerWidth : 0,
		containerHeight : 0,
		objects : [],
	};

	this.enterScene = function(callback, sender)
	{
		scope.context.composer.enterEffect(callback, sender);
	};

	this.exitScene = function(callback, sender)
	{
		scope.context.composer.exitEffect(callback, sender);
	};

	this.isVisible = function()
	{
		return this.visible;
	};

	this.setVisible = function(visible)
	{
		this.visible = visible;
		this.context.controls.enabled = visible;
	};

	this.addObjectToBaseScene = function(object)
	{
		this.context.objects.push(object);
		this.context.baseScene.add(object);
	};

	this.addObjectToMainScene = function(object)
	{
		this.context.objects.push(object);
		this.context.mainScene.add(object);
	};

	this.addObjectToEffectScene = function(object)
	{
		this.context.objects.push(object);
		this.context.effectScene.add(object);
	};

	this.reset = function()
	{

	};

	this.start = function()
	{

	};

	this.stop = function()
	{

	};

	this.onSize = function()
	{
		this.context.containerWidth = window.innerWidth;
		this.context.containerHeight = window.innerHeight;

		this.context.baseCamera.aspect = window.innerWidth / window.innerHeight;
		this.context.baseCamera.updateProjectionMatrix();
		this.context.mainCamera.aspect = window.innerWidth / window.innerHeight;
		this.context.mainCamera.updateProjectionMatrix();

		this.context.renderer.setSize( window.innerWidth, window.innerHeight );
		this.context.composer.setSize(window.innerWidth, window.innerHeight);
	};

	this.onRender = function()
	{
		if (!this.visible) {
			return;
		}

		scope.context.containerWidth = window.innerWidth;
		scope.context.containerHeight = window.innerHeight;
		scope.context.controls.update();

		for (var i = 0; i < scope.context.objects.length; i++) {
			scope.context.objects[i].update();
		}

		scope.context.renderer.setClearColor( 0x001862, 1.0 );
		scope.context.renderer.clear(true, true, true);

		//scope.context.renderer.render(this.context.effectScene, this.context.mainCamera);
		scope.context.composer.render(0.1);
	};

	this.context.container = this.domElement;
	this.context.renderer = this.config.renderer;

	this.context.baseCamera = new THREE.PerspectiveCamera( this.config.camera.fieldOfView, window.innerWidth / window.innerHeight, this.config.camera.near, this.config.camera.far );
	this.context.baseCamera.position.z = 2000;
	var baseScene = new THREE.Scene();
	var baseAmbientLight = new THREE.AmbientLight( 0x888888 );
	baseScene.add( baseAmbientLight );
	var baseDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	baseDirectional.position.set( -1000000, -1000000, 1000000 );
	baseScene.add( baseDirectional );
	baseScene.updateMatrix();
	scope.context.baseScene = baseScene;
	//this.addObjectToBaseScene(new KMG.BackgroundPlaneObject(this.context, this.config));

	this.context.mainCamera = new THREE.PerspectiveCamera( this.config.camera.fieldOfView, window.innerWidth / window.innerHeight, this.config.camera.near, this.config.camera.far );
	this.context.mainCamera.position.z = 2000;
	var mainScene = new THREE.Scene();
	var mainAmbientLight = new THREE.AmbientLight( 0x888888 );
	mainScene.add( mainAmbientLight );
	var mainDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	mainDirectional.position.set( -1000000, -1000000, 1000000 );
	mainScene.add( mainDirectional );
	mainScene.updateMatrix();
	scope.context.mainScene = mainScene;

	var effectScene = new THREE.Scene();
	var effectAmbientLight = new THREE.AmbientLight( 0x888888 );
	effectScene.add( effectAmbientLight );
	var effectDirectional = new THREE.DirectionalLight( 0xFFFFFF, 2.0);
	effectDirectional.position.set( -1000000, -1000000, 1000000 );
	effectScene.add( effectDirectional );
	effectScene.updateMatrix();
	this.context.effectScene = effectScene;

	this.addObjectToMainScene(new KMG.LocalGridObject(this.context, this.config));
	this.addObjectToMainScene(new KMG.LocalModelObject(this.context, this.config));

	this.context.composer = new KMG.PlaneEffectsComposer(this.context, this.context.renderer);
	this.context.objects.push(this.context.composer);

    this.context.controls = new THREE.OrbitControls(this.context.mainCamera,this.context.renderer.domElement );
    this.context.controls.maxDistance = 2000;
    this.context.controls.update(true);
};